<template>
  <i :style="style" :class="$cn('icon', props.class)" />
</template>
<script lang="ts" setup>
import type { CSSProperties } from "vue";

const props = defineProps({
  name: {
    type: String,
    required: true,
  },
  class: {
    type: String,
    default: "",
  },
});
const style = ref<CSSProperties>({});

onMounted(async () => {
  // 根据名称获取到svg文件内容，raw模式可以获取文本内容
  const module = await import(`@/assets/icons/${props.name}.svg?raw`);
  style.value = svgToCss(module.default);
});
/**
 * @param svg svg字符串
 * @returns svg 转义后的svg字符串
 * @description 处理svg文件，避免存在换行，或者符号问题
 */
function encodeSvg(svg: string) {
  return svg
    .replace(
      "<svg",
      ~svg.indexOf("xmlns") ? "<svg" : '<svg xmlns="http://www.w3.org/2000/svg"'
    )
    .replace(/"/g, "'")
    .replace(/%/g, "%25")
    .replace(/#/g, "%23")
    .replace(/\{/g, "%7B")
    .replace(/\}/g, "%7D")
    .replace(/</g, "%3C")
    .replace(/[\r\n\t]/g, "")
    .replace(/>/g, "%3E");
}
function isMonochrome(svgText: string) {
  const parser = new DOMParser();
  const svgDoc = parser.parseFromString(svgText, "image/svg+xml");
  const elements = svgDoc.querySelectorAll("*");

  let colors = new Set();

  elements.forEach((el) => {
    // 检查fill属性
    if (el.hasAttribute("fill") && el.getAttribute("fill") !== "none") {
      colors.add(el.getAttribute("fill"));
      console.log(el.getAttribute("fill"));
    }
    // 检查stroke属性
    if (el.hasAttribute("stroke") && el.getAttribute("stroke") !== "none") {
      colors.add(el.getAttribute("stroke"));
    }
    // 检查样式中的fill和stroke
    if (el.hasAttribute("style")) {
      const style = el.getAttribute("style");
      const fillMatch = style?.match(/fill:\s*([^;]+)/);
      const strokeMatch = style?.match(/stroke:\s*([^;]+)/);
      if (fillMatch && fillMatch[1] !== "none") colors.add(fillMatch[1]);
      if (strokeMatch && strokeMatch[1] !== "none") colors.add(strokeMatch[1]);
    }
  });

  // 移除透明和继承值
  colors.delete("currentColor");
  colors.delete("inherit");
  colors.delete("transparent");

  // 如果颜色数量<=1且不包含渐变/图案，则为单色
  return (
    colors.size <= 1 &&
    !svgText.includes("linearGradient") &&
    !svgText.includes("radialGradient") &&
    !svgText.includes("pattern")
  );
}
/**
 * @param svg svg字符串
 * @returns css样式
 * @description 将svg转换为css样式
 */
function svgToCss(svg: string) {
  const uri = `url("data:image/svg+xml;utf8,${encodeSvg(svg)}")`;
  if (isMonochrome(svg)) {
    // 单色图标，颜色随文字颜色变化
    return {
      mask: `${uri} no-repeat`,
      "mask-size": "100% 100%",
      "background-color": "currentColor",
      height: "1em",
      width: "1em",
    };
  } else {
    // 彩色图标。不改变颜色
    return {
      background: `${uri} no-repeat`,
      "background-size": "100% 100%",
      "background-color": "transparent",
      height: "1em",
      width: "1em",
    };
  }
}
</script>

<style scoped>
.icon {
  display: inline-block;
  /* width: 50px; */
}
</style>
